package cn.fr.util;

import cn.fr.config.ConfConstConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Queue;
import java.util.concurrent.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

@Component
public class TaskWorks {
    private static Logger logger = LoggerFactory.getLogger("PROJECT_LOGGER");
    private  final ReentrantLock lock = new ReentrantLock();
    private  final Condition notFull = lock.newCondition();
    private  final Condition notEmpty = lock.newCondition();
    private  ConfConstConfig confConstConfig;
    @Autowired
    public void setConfConstConfig(ConfConstConfig confConstConfig) {
        this.confConstConfig = confConstConfig;
    }

    // 创建调度任务线程池
    ScheduledExecutorService scheduled = new ScheduledThreadPoolExecutor(1);

    ThreadPoolExecutor pool = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
            2*Runtime.getRuntime().availableProcessors(),60L,TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(10),new ThreadPoolExecutor.CallerRunsPolicy());

    public void startTask(){
        try {
            logger.info("开始执行任务");
            LinkedBlockingQueue<String> taskQueue = new LinkedBlockingQueue(confConstConfig.getQueueSize());

            beginProduct(taskQueue);

            beginConsume(taskQueue);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    //生产任务
    private void beginProduct(LinkedBlockingQueue taskQueue){
        //按照固定10毫秒时间执行
        logger.info("开始执行生产任务");
        scheduled.scheduleAtFixedRate(new ProductTaskToQueue(taskQueue,confConstConfig.getQueueSize(),lock,notFull,notEmpty),
                     confConstConfig.getInitialDelay(),confConstConfig.getPeriod(), TimeUnit.valueOf(confConstConfig.getUnit()));
        //关闭线程池
//        scheduled.shutdown();
    }
    //消费任务
    private void beginConsume(LinkedBlockingQueue<String>  taskQueue){
        logger.info("开始执行消费任务");
        while(true){

            //获取独占锁
            lock.lock();
            try {
                //队列空，则等待
                while (0 == taskQueue.size()) {
                    logger.info("消费者调用await");
                    notFull.await();
                }
                for (int i = 0; i < taskQueue.size(); i++) {
                    String taskUrl = taskQueue.poll();
                    pool.submit(new CustomerTaskFromQueue(taskUrl));
                }
                //唤醒生产线程
                notEmpty.signalAll();
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                //释放锁
                lock.unlock();
            }


        }
//        pool.shutdown();
    }


}
